import math
import sys

from PyQt5.QtCore import Qt, QRectF, QTimer
from PyQt5.QtGui import QColor, QFont, QPainter, QRadialGradient, QPolygon, QPen
from PyQt5.QtWidgets import QApplication, QWidget, QLCDNumber, QFrame, QPushButton, QLabel, QHBoxLayout, QVBoxLayout
from uiDef import *

class CarInfoWidget(QWidget):
    def __init__(self, parent=None):
        super(CarInfoWidget, self).__init__(parent)
        self.lcd = QLCDNumber(self)
        
        #返回主界面
        self.homeBtn = QPushButton(self)
        self.homeBtn.setStyleSheet("QPushButton{border-image: url(resource/ic_home.png)}")
        self.homeBtn.setFixedSize(30, 30)
        self.headerLabel = QLabel(self)
        self.headerLabel.setText("汽车时速")
        self.headerLabel.setStyleSheet("color:white")
        self.hBoxHeader = QHBoxLayout()
        self.hBoxHeader.addStretch(1)
        self.hBoxHeader.addWidget(self.headerLabel)
        self.hBoxHeader.addStretch(1)
        self.hBoxHeader.addWidget(self.homeBtn)
        
        #整体布局
        self.vboxMain = QVBoxLayout()
        self.vboxMain.addLayout(self.hBoxHeader)
        self.vboxMain.addStretch(1)
        self.setLayout(self.vboxMain)

        # 颜色设置
        self.pieColorStart = QColor(63, 191, 127)  
        self.pieColorMid = QColor(0, 0, 205)  
        self.pieColorEnd = QColor(222, 0, 0)  
        self.pointerColor = QColor(245, 245, 245) 
        self.startAngle = 60
        self.endAngle = 60
        self.minValue = 0
        self.maxValue = 200
        self.currentValue = 0
        self.testDir = "up"
        self.scaleMajor = 8
        self.font = QFont("宋体", 6)
        self.font.setBold(True)
        self.lcd_init()
        
        # 定时器
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.updateShow)
        self.timer.start(20)
        
        #信号与槽
        self.homeBtn.clicked.connect(self.returnHome)
        self.homeBtn.clicked.connect(self.close)
        
        self.initUI()
        
    # 初始化界面
    def initUI(self):
        self.resize(WIN_WIDTH, WIN_HEIGHT)
        self.setWindowTitle('汽车信息')
        self.setStyleSheet("background-color:rgb(0,0,0)")
        self.show()

    def updateShow(self):
        try:
            if (self.testDir == "up"):
                if (self.currentValue < 120):
                    self.currentValue = self.currentValue + 1
                else:
                    self.testDir = "down"
            else:
                if (self.currentValue > 0):
                    self.currentValue = self.currentValue - 1
                else:
                    self.testDir = "up"
            #print(self.currentValue)
            self.update()
        except Exception as e:
            print(e)
            
    def paintEvent(self, event):
        try:
            # 坐标轴变换 默认640*480
            width = self.width()
            height = self.height()

            painter = QPainter(self)  # 初始化painter
            painter.translate(width / 2, height / 5 * 3)  # 坐标轴变换，调用translate()将坐标原点平移至窗口中心

            # 坐标刻度自适应
            side = min(width, height)
            painter.scale(side / 200.0, side / 200.0)
            # 本项目中将坐标缩小为side/200倍，即画出length=10的直线，其实际长度应为10*(side/200)。

            # 启用反锯齿，使画出的曲线更平滑
            painter.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing)
            painter.begin(self)

            # 开始画图
            self.drawColorPie(painter)
            self.drawPointerIndicator(painter)
            self.drawLine(painter)
            self.drawText(painter)

            self.lcd.setGeometry((int)(self.width() / 2.35), (int)(self.height() / 9 * 7.8), (int)(self.width() / 10),
                                 (int)(self.height() / 10))  
            formValue = "%d" % self.currentValue  # 数值的格式化显示
            self.lcd.display(formValue)  # 将指针所指的值显示在LCD屏幕上
        except Exception as e:
            print(e)

    def drawColorPie(self, painter):  # 绘制三色环
        painter.save() 
        # 设置扇形部分区域
        radius = 99  # 半径
        painter.setPen(Qt.NoPen)
        rect = QRectF(-radius, -radius, radius * 2, radius * 2)  # 扇形所在圆区域

        # 计算三色圆环范围角度。green：blue：red = 1：2：1
        angleAll = 360.0 - self.startAngle - self.endAngle  # self.startAngle = 45, self.endAngle = 45
        angleStart = angleAll * 0.25
        angleMid = angleAll * 0.5
        angleEnd = angleAll * 0.25

        # 圆的中心部分填充为透明色，形成环的样式
        rg = QRadialGradient(0, 0, radius, 0, 0)  # 起始圆心坐标，半径，焦点坐标
        ratio = 0.85  # 透明：实色 = 0.8 ：1

        # 绘制绿色环
        rg.setColorAt(0, Qt.transparent)  # 透明色
        rg.setColorAt(ratio, Qt.transparent)
        rg.setColorAt(ratio + 0.01, self.pieColorStart)
        rg.setColorAt(1, self.pieColorStart)
        painter.setBrush(rg)
        painter.drawPie(rect, (int)(270 - self.startAngle - angleStart) * 16, (int)(angleStart) * 16)

        # 绘制蓝色环
        rg.setColorAt(0, Qt.transparent)
        rg.setColorAt(ratio, Qt.transparent)
        rg.setColorAt(ratio + 0.01, self.pieColorMid)
        rg.setColorAt(1, self.pieColorMid)
        painter.setBrush(rg)
        painter.drawPie(rect, (int)(270 - self.startAngle - angleStart - angleMid) * 16, (int)(angleMid) * 16)

        # 绘制红色环
        rg.setColorAt(0, Qt.transparent)
        rg.setColorAt(ratio, Qt.transparent)
        rg.setColorAt(ratio + 0.01, self.pieColorEnd)
        rg.setColorAt(1, self.pieColorEnd)
        painter.setBrush(rg)
        painter.drawPie(rect, (int)(270 - self.startAngle - angleStart - angleMid - angleEnd) * 16, (int)(angleEnd) * 16)

        painter.restore()  

    def drawPointerIndicator(self, painter):
        painter.save()
        # 绘制指针
        radius = 58  # 指针长度
        painter.setPen(Qt.NoPen)
        painter.setBrush(self.pointerColor)

        # (-5, 0), (0, -8), (5, 0)和（0, radius) 四个点绘出指针形状
        # 绘制多边形做指针
        pts = QPolygon()
        pts.setPoints(-5, 0, 0, -8, 5, 0, 0, radius)
        # print("radius:" + str(radius))

        # 旋转指针，使得指针起始指向为0刻度处
        painter.rotate(self.startAngle)
        degRotate = (360.0 - self.startAngle - self.endAngle) / (self.maxValue - self.minValue) \
                    * (self.currentValue - self.minValue)
        painter.rotate(degRotate)
        painter.drawConvexPolygon(pts)
        painter.restore()

    def drawText(self, painter):
        painter.save()
        # 绘制刻度值
        startRad = 4
        deltaRad = 0.6
        radius = 63
        offset = 0.5
        for i in range(self.scaleMajor + 1):  # self.scaleMajor = 8, 8个主刻度
            # 正余弦计算
            sina = math.sin(startRad - i * deltaRad)
            cosa = math.cos(startRad - i * deltaRad)

            # 刻度值计算
            value = math.ceil((1.0 * i * (
                    (self.maxValue - self.minValue) / self.scaleMajor) + self.minValue))
            # math.ceil(x)：返回不小于x的最小整数
            strValue = str(int(value))

            # 字符的宽度和高度
            textWidth = self.fontMetrics().width(strValue)
            textHeight = self.fontMetrics().height()

            # 字符串的起始位置。注意考虑到字符宽度和高度进行微调
            x = radius * cosa - textWidth / 2
            y = -radius * sina + textHeight / 4

            painter.setFont(self.font)
            painter.setPen(QColor(255, 255, 255))  # 还是用自己选的颜色
            painter.drawText((int)(x - offset), (int)(y), strValue)
            # Y为自己加的单位，可以不加，直接在 Title 中进行总体设置也行
        painter.restore()

    def drawLine(self, painter):
        painter.save()
        # 绘制刻度线
        # print("drawLine")
        radius = 79
        painter.rotate(self.startAngle)  # self.startAngle = 45,旋转45度
        steps = self.scaleMajor  # 8个刻度
        angleStep = (360.0 - self.startAngle - self.endAngle) / steps  # 刻度角
        for i in range(steps + 1):
            if i < 3:
                color = self.pieColorStart
            elif i < 7:
                color = self.pieColorMid
            else:
                color = self.pieColorEnd
            painter.setPen(QPen(color, Qt.SolidLine))
            painter.drawLine(0, radius - 5, 0, radius)
            painter.rotate(angleStep)
        painter.restore()

    def lcd_init(self):
        self.lcd.setSmallDecimalPoint(False)  # False：小数点单独占一位；True：小数点不占位
        self.lcd.setDigitCount(3)  # 最多显示2位数字
        self.lcd.setFrameStyle(QFrame.NoFrame)  # 无边框
        self.lcd.setMode(QLCDNumber.Dec)  # 十进制显示
        self.lcd.setStyleSheet("color: rgb(255, 255, 255)")  # 显示数字的颜色
        self.lcd.setSegmentStyle(QLCDNumber.Flat)  # 数字显示样式为flat，不向外凸
        
    # 返回主页
    def returnHome(self):
        print("return home")
        from homeUI import mainWindow
        self.homeWindow = mainWindow()
        self.homeWindow.show()

if __name__ =='__main__':
    app = QApplication(sys.argv)
    my_widget = CarInfoWidget()
    my_widget.show()
    sys.exit(app.exec())
